#!/usr/bin/python
# -*- coding: UTF-8 -*-
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt  # 绘图库

"""
这里是一个非常好的大数据验证结果，随着数据量的上升，集合的结果也越来越接近真实值，
这也是反馈神经网络的一个比较好的应用
这里不是很需要各种激励函数
而对于dropout，这里可以看到加上dropout，loss的值更快
随着数据量的上升，结果就更加接近于真实值。
"""
# 使用NumPy的随机生成数据功能生成一个y=4x+1的线性曲线，数据inputX、noise为随机生成的输入数与满足偏差为0.05的正态分布的噪音数
inputX = np.random.rand(3000, 1)
noise = np.random.normal(0, 0.05, inputX.shape)
outputY = inputX * 4 + 1 + noise
print("------inputX")
print(inputX)
print("------noise")
print(noise)
print("------outputY")
print(outputY)
print("------")
# 创建了有一个隐藏层的反馈神经网络去计算这个线性曲线
# 神经网络隐藏层的变量，这两个变量在后续的图计算过程中需要重新根据误差不停地重新赋值，所以设置为tf变量
weight1 = tf.Variable(np.random.rand(inputX.shape[1], 4))
bias1 = tf.Variable(np.random.rand(inputX.shape[1], 4))

# 占位符，作用是在tf图计算时不停地输入数据
x1 = tf.placeholder(tf.float64, [None, 1])
# 神经网络设立的模型目标，形式为 Y=x*w+b，即这是一个一元线性回归模型
y1_ = tf.matmul(x1, weight1) + bias1

y = tf.placeholder(tf.float64, [None, 1])
# 损失函数，这里采用的是最小二乘法的损失函数，即计算模型输出值与真实值之间的误差的最小二乘法
loss = tf.reduce_mean(tf.reduce_sum(tf.square((y1_ - y)), reduction_indices=[1]))

train = tf.train.GradientDescentOptimizer(0.25).minimize(loss)  # 选择梯度下降的训练方法

# 数据初始化
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

for i in range(1000):
    sess.run(train, feed_dict={x1: inputX, y: outputY})
print(sess.run([weight1, bias1]))

x_data = np.matrix([[1.], [2.], [3.]])
print(sess.run(y1_, feed_dict={x1: x_data}))


# 画样本点
plt.figure(figsize=(8, 6))       # 指定图像比例： 8：6
plt.scatter(inputX, outputY, color="green", label="sample data", linewidth=2)
plt.plot(inputX, sess.run(weight1)*inputX + sess.run(bias1))
plt.xlabel('x')
plt.xlim(-2,2)
plt.ylabel('y')
plt.legend()
plt.show()
